package com.oto.service;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.IKSegmentation;
import org.wltea.analyzer.Lexeme;

import com.oto.model.FlowDO;
import com.oto.model.IndexDO;

/**
 * @author xueqiang.mi
 * @since 2011-1-16
 */
@Service
public class SearchService extends BaseService {

	@Autowired
	protected IndexService indexService;

	public Set<String> parse(String key) {
		Reader input = new StringReader(key);
		IKSegmentation segmentation = new IKSegmentation(input);
		Set<String> keys = new TreeSet<String>(new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				int i = o2.length() - o1.length();
				return i == 0 ? 1 : i;
			}
		});
		try {
			Lexeme lexeme = segmentation.next();
			while (lexeme != null) {
				keys.add(lexeme.getLexemeText());
				lexeme = segmentation.next();
			}
		} catch (IOException e) {
			// Ignore
		}
		return keys;
	}

	public List<FlowDO> search(Set<String> keys, int resultNumber) {
		Map<Long, Integer> hitMap = new HashMap<Long, Integer>();
		// 执行不超过N次搜索
		for (int i = 0; i < 5 && i < keys.size(); i++) {
			IndexDO indexDO = indexService.getIndex(keys.toArray()[i].toString());
			if (indexDO != null) {
				Set<Long> flowIds = indexDO.getFlows();
				stat(hitMap, flowIds);
			}
		}

		// 排序flowId
		List<Map.Entry<Long, Integer>> entries = new ArrayList<Map.Entry<Long, Integer>>(hitMap.entrySet());
		Collections.sort(entries, new Comparator<Map.Entry<Long, Integer>>() {
			@Override
			public int compare(Entry<Long, Integer> o1, Entry<Long, Integer> o2) {
				return o2.getValue() - o1.getValue();
			}
		});

		// 查询出搜索结果中排名前N的flow
		List<FlowDO> result = new ArrayList<FlowDO>();
		for (int i = 0; i < resultNumber && i < entries.size(); i++) {
			FlowDO flow = get(FlowDO.class, entries.get(i).getKey());
			result.add(flow);
		}
		return result;
	}

	private void stat(Map<Long, Integer> hitMap, Set<Long> ids) {
		for (Long id : ids) {
			if (hitMap.containsKey(id)) {
				hitMap.put(id, hitMap.get(id) + 1);
			} else {
				hitMap.put(id, 1);
			}
		}
	}
}
